﻿using System;
using System.Collections.Generic;

namespace UploadClient.Interfaces.Upload
{
    /// <summary>
    /// Represents the method that will handle the UploadComplete event of a Upload class.
    /// </summary>
    /// <param name="args">A UploadEventArgs that contains the event data.</param>
    public delegate void UploadCompleteEventHandler(UploadEventArgs args);

    /// <summary>
    /// Represents the method that will handle the UploadProgress event of Upload class.
    /// </summary>
    /// <param name="args">A UploadProgressEventArgs that contains the event data.</param>
    public delegate void UploadProgressEventHandler(UploadProgressEventArgs args);

    /// <summary>
    /// Interface for a upload provider.
    /// </summary>
    public interface IUploadProvider : IDisposable
    {
        /// <summary>
        /// Returns true if there are still files in the upload que.
        /// </summary>
        bool IsBusy {get;}

        /// <summary>
        /// Initialize the class.
        /// </summary>
        void Init(IUploadHost host);

        /// <summary>
        /// Initialize the class with configuration settings.
        /// </summary>
        /// <param name="settings"></param>
        void Init(IUploadHost host, IUploadConfig settings);

        /// <summary>
        /// Returns the upload provider configuration.
        /// </summary>
        /// <returns>Returns a list with configurations.</returns>
        IEnumerable<IUploadConfig> GetConfiguration();

        /// <summary>
        /// Adds files to the upload que and starts upload if he isn´t running. 
        /// </summary>
        /// <param name="items">Array of UploadItems.</param>
        void UploadFiles(params IUploadItem[] items);

        /// <summary>
        /// Cancel the upload and delete que.
        /// </summary>
        void CancelUpload();

        /// <summary>
        /// Returns a integer that indicates how many files are still in the upload que.
        /// </summary>
        /// <returns>An integer.</returns>
        int GetRemainingQueCount();

        /// <summary>
        /// Returns an integer that indicaates how many files are successfully uploaded.
        /// </summary>
        /// <returns>An integer.</returns>
        int GetFinishedFilesCount();

        /// <summary>
        /// Occurs when the upload operation has completed, has been canceled, or has raised an exception.
        /// </summary>
        event UploadCompleteEventHandler UploadComplete;

        /// <summary>
        /// Occurs when ReportProgress is called.
        /// </summary>
        event UploadProgressEventHandler UploadProgress;
    }

    /// <summary>
    /// The UploadEventArgs contains event data that is used by the UploadCompleteEventHandler.
    /// </summary>
    public class UploadEventArgs
    {
        /// <summary>
        /// Initialize UploadEventArgs.
        /// </summary>
        /// <param name="guid">Identifies the sender.</param>
        /// <param name="error">Gets a value indicating which error occurred during an operation.</param>
        /// <param name="cancelled">Gets a value indicating whether an operation has been canceled.</param>
        /// <param name="result">Gets a value that represents the result of an operation.</param>
        public UploadEventArgs(Guid guid, Exception error, bool cancelled, string result)
        {
            Guid = guid;
            Error = error;
            Cancelled = cancelled;
            Result = result;
        }

        /// <summary>
        /// Identifies the sender.
        /// </summary>
        public Guid Guid { get; private set; }

        /// <summary>
        /// Gets a value indicating which error occurred during an operation.
        /// </summary>
        public Exception Error { get; private set; }

        /// <summary>
        /// Gets a value indicating whether an operation has been canceled.
        /// </summary>
        public bool Cancelled { get; private set; }
        
        /// <summary>
        /// Gets a value that represents the result of an operation.
        /// </summary>
        public string Result { get; private set; }
    }

    /// <summary>
    /// The UploadProgressEventArgs contains event data that is used by the UploadProgressEventHandler.
    /// </summary>
    public class UploadProgressEventArgs
    {
        /// <summary>
        /// Initialize UploadEventArgs.
        /// </summary>
        /// <param name="guid">Identifies the sender.</param>
        /// <param name="progressPercentage">Gets the task progress percentage.</param>
        /// <param name="userState">Gets a status message.</param>
        public UploadProgressEventArgs(Guid guid, int progressPercentage, string message)
        {
            Guid = guid;
            ProgressPercentage = progressPercentage;
            Message = message;
        }

        /// <summary>
        /// Identifies the sender.
        /// </summary>
        public Guid Guid { get; private set; }

        /// <summary>
        /// Gets the task progress percentage.
        /// </summary>
        public int ProgressPercentage { get; private set; }
        
        /// <summary>
        /// Gets a status message.
        /// </summary>
        public string Message { get; private set; }
    }
}
